package strategies;

//~--- non-JDK imports --------------------------------------------------------

import com.dukascopy.api.Period;

//~--- JDK imports ------------------------------------------------------------

import java.text.ParseException;
import java.text.SimpleDateFormat;

import java.util.Date;
import java.util.Map;

/**
 * Class representing strategy arguments
 */
public class StrategyArgs {
    private double  AF                      = 0.003;
    private double  EAF                     = 0.01;
    private double  XAF                     = 0.02;
    private int     candleThreshold         = 20;
    private double  initialDeposit          = 1000.0;
    private int     leverage                = 10;
    private int     maxConsecutivePositions = 2;
    private double  stopLoss                = 300;
    private double  takeProfit              = 600;
    private Period  period                  = Period.FIVE_MINS;
    private boolean compoundedTrade         = false;
    private Date    endDate;
    private Date    startDate;
    private static SimpleDateFormat format  = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    private double minTakeProfit;

  /**
   * Create new instance of StrategyArgs by loading the arguments from given map.
   * Note: All the variables are expected
   * @param args strategy argument and value map
   * @throws ParseException thrown when invalid data is given
   */
  public StrategyArgs(Map<String, String> args) throws ParseException {
        // Load values from arguments
        setAF(Double.parseDouble(args.get("AF")));
        setEAF(Double.parseDouble(args.get("EAF")));
        setXAF(Double.parseDouble(args.get("XAF")));
        setCandleThreshold(Integer.parseInt(args.get("candleThreshold")));
        setInitialDeposit(Integer.parseInt(args.get("initialDeposit")));
        setLeverage(Integer.parseInt(args.get("leverage")));
        setMaxConsecutivePositions(Integer.parseInt(args.get("maxConsecutivePositions")));
        setTakeProfit(Double.parseDouble(args.get("stopLoss")));
        setTakeProfit(Double.parseDouble(args.get("takeProfit")));
        setPeriod(Period.valueOf(args.get("period")));
        setCompoundedTrade(Boolean.parseBoolean(args.get("compoundedTrade")));

        // Set start and end date
        setStartDate(format.parse(args.get("startDate")));
        setEndDate(format.parse(args.get("endDate")));
    }

  /**
   * Create new instance of StrategyArgs by using the arguments passed
   * @param candleThreshold Number of candles for which trend has to persist before its being considered for trading
   * @param takeProfit in pips
   * @param stopLoss in pips
   * @param maxConsecutivePositions Maximum number consecutive of trade positions that can be taken in one direction
   * @param period for which Strategy will be traded
   * @param startDate simulation start time
   * @param endDate simulation end date
   * @param leverage leverage for this strategy
   * @param initialDeposit initial deposit
   * @param aF Accelerating factor
   * @param eAF
   * @param xAF
   * @param compoundTrade should simulation use cumulative investment
   * @throws ParseException Thrown when start or end date is of incorrect format
   */
    public StrategyArgs(int candleThreshold, double takeProfit, double stopLoss, int maxConsecutivePositions,
                        Period period, String startDate, String endDate, int leverage, int initialDeposit, double aF,
                        double eAF, double xAF, boolean compoundTrade) throws ParseException {
        // Set arguments
        this.candleThreshold         = candleThreshold;
        this.takeProfit              = takeProfit;
        this.stopLoss                = stopLoss;
        this.maxConsecutivePositions = maxConsecutivePositions;
        this.period                  = period;
        this.compoundedTrade         = compoundTrade;
        this.startDate = format.parse(startDate);
        this.endDate   = format.parse(endDate);
        this.leverage       = leverage;
        this.initialDeposit = initialDeposit;
        EAF                 = eAF;
        XAF                 = xAF;
        AF                  = aF;
    }

  /**
   * @return Stop loss for this strategy
   */
    public double getStopLoss() {
        return stopLoss;
    }

  /**
   * Set the stop loss
   * @param stopLoss  stop loss
   */
    public void setStopLoss(double stopLoss) {
        this.stopLoss = stopLoss;
    }

  /**
   * Sets the number of candles as threshold
   * @param candleThreshold number of candles
   */
    void setCandleThreshold(int candleThreshold) {
        this.candleThreshold = candleThreshold;
    }

  /**
   * Gets the candle threshold
   */
    public int getCandleThreshold() {
        return candleThreshold;
    }

  /**
   * Sets take profit
   * @param takeProfit in pips
   */
    void setTakeProfit(double takeProfit) {
        this.takeProfit = takeProfit;
    }

  /**
   * Gets take profit in pips
   */
    public double getTakeProfit() {
        return takeProfit;
    }

  /**
   * Sets max consecutive trading positions in one direction
   * @param maxConsecutivePositions number of consecutive positions
   */
    void setMaxConsecutivePositions(int maxConsecutivePositions) {
        this.maxConsecutivePositions = maxConsecutivePositions;
    }

  /**
   * Gets max consecutive trading positions in one direction
   */
    public int getMaxConsecutivePositions() {
        return maxConsecutivePositions;
    }

  /**
   * Sets indicator period
   * @param period period
   */
    void setPeriod(Period period) {
        this.period = period;
    }

  /**
   * Gets the indicator period
   */
    public Period getPeriod() {
        return period;
    }

  /**
   * Sets the simulation start time
   * @param startDate date
   */
    void setStartDate(Date startDate) {
        this.startDate = startDate;
    }

  /**
   * Gets the indicator start date
   */
    public Date getStartDate() {
        return startDate;
    }

  /**
   * Sets the simulation end time
   * @param endDate date
   */
    void setEndDate(Date endDate) {
        this.endDate = endDate;
    }

  /**
   * Gets simulation end time
   */
    public Date getEndDate() {
        return endDate;
    }

  /**
   * Sets maximum leverage
   * @param leverage
   */
    void setLeverage(int leverage) {
        this.leverage = leverage;
    }

  /**
   * Gets the leverage
   */
    public int getLeverage() {
        return leverage;
    }

  /**
   * Sets the initial deposit
   * @param initialDeposit in dollars
   */
    void setInitialDeposit(double initialDeposit) {
        this.initialDeposit = initialDeposit;
    }

  /**
   * Gets the initial deposit in dollars
   */
    public double getInitialDeposit() {
        return initialDeposit;
    }

  /**
   * Gets EAF
   */
    public double getEAF() {
        return EAF;
    }

   /**
   * Sets EAF
   */
    public void setEAF(double EAF) {
        this.EAF = EAF;
    }

  /**
   * Gets AF
   */
    public double getAF() {
        return AF;
    }

  /**
   * Sets AF
   */
    public void setAF(double AF) {
        this.AF = AF;
    }

  /**
   * Gets XAF
   */
    public double getXAF() {
        return XAF;
    }

  /**
   * Sets XAF
   */
    public void setXAF(double XAF) {
        this.XAF = XAF;
    }

  /**
   * Set if the trading amount to be compounded or not
   * @param compoundedTrade flag indicating trade to be compounded or not
   */
    public void setCompoundedTrade(boolean compoundedTrade) {
        this.compoundedTrade = compoundedTrade;
    }

  /**
   * Indicates whether strategy is using trade amount compounding or not
   */
    public boolean isCompoundedTrade() {
        return compoundedTrade;
    }

  /**
   * All arguments in a single string
   */
  @Override
  public String toString() {
    StringBuilder    builder    = new StringBuilder();
    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy_MM_dd__HH_mm_ss");

    builder.append("StrategyArgs_startdate_").append(dateFormat.format(startDate)).append("_enddate_").append(
        dateFormat.format(endDate)).append("_initialdeposit_").append(initialDeposit).append("_leverage_").append(
        leverage).append("_maxconsecutivepositions_").append(maxConsecutivePositions).append("_period_").append(
        period).append("_takeprofit_").append(takeProfit).append("_threshold_").append(candleThreshold);

    return builder.toString();
  }

  public double getMinTakeProfit() {
    return minTakeProfit;
  }

  public void setMinTakeProfit(double minTakeProfit) {
    this.minTakeProfit = minTakeProfit;
  }
}

//~ Formatted by Jindent --- http://www.jindent.com
